/*********************************************************************************
 * PROJECT: MiMic
 * --------------------------------------------------------------------------------
 *
 * This file is part of MiMic
 * Copyright (C)2011 Ryo Iizuka
 *
 * MiMic is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by　the Free Software Foundation, either version 3 of the　License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * For further information please contact.
 *	http://nyatla.jp/
 *	<airmail(at)ebony.plala.or.jp> or <nyatla(at)nyatla.jp>
 *
 *********************************************************************************/
#ifndef NyLPC_stdlib_h
#define NyLPC_stdlib_h

#define NyLPC_ARCH_WIN32 1
#define NyLPC_ARCH_FREERTOS 2

#ifdef WIN_DEBUG
	#define NyLPC_ARCH NyLPC_ARCH_WIN32
#else
	#define NyLPC_ARCH NyLPC_ARCH_FREERTOS
#endif

#if NyLPC_ARCH==NyLPC_ARCH_FREERTOS
	#include "FreeRTOS.h"
	#include "semphr.h"
	#include "task.h"
#elif NyLPC_ARCH==NyLPC_ARCH_WIN32
#else
#error Bad NyLPC_ARCH!
#endif

#include <string.h>
/**********************************************************************
 *
 * ASSERT/ABORT
 *
 **********************************************************************/
/**
 * 引数チェック専用のASSERT
 */
#define NyLPC_ArgAssert(e) if(!(e)){NyLPC_assertHook(NULL,-1);};

/**
 *　アサート。リリース時には消えます。リリース時には無効です。
 */
#define NyLPC_Assert(e) if(!(e)){NyLPC_assertHook(NULL,-1);};
/**
 * デバックの為のフック。リリース時には無効です。
 */
#define NyAR_DebugHook() {NyLPC_debugHook(__FILE__,__LINE__);};
/**
 * Abortマクロ。リリース時も有効です。
 */
#define NyLPC_Abort() {NyLPC_abortHook(__FILE__,__LINE__);};	//もうだめ
/**
 * Abortマクロ。リリース時も有効です。
 */
#define NyLPC_AbortIfNot(e) if(!(e)){NyLPC_abortHook(__FILE__,__LINE__);};
/**
 * 警告マクロ。リリース時は無効です。
 */
#define NyLPC_Warning() {NyLPC_debugHook(__FILE__,__LINE__);};
/**
 * 警告マクロ。リリース時は無効です。
 */
#define NyLPC_WarningIfNot(e) if(!(e)){NyLPC_debugHook(__FILE__,__LINE__);};
/*
 * トレースマクロ。
 * リリース時は無効です。
 */
#define NyLPC_Trace() {NyLPC_debugHook(__FILE__,__LINE__);};


void NyLPC_assertHook(const char* m,int l);
void NyLPC_abortHook(const char* m,int l);
void NyLPC_debugHook(const char* m,int l);

extern unsigned int NyLPC_assert_counter;
extern unsigned int NyLPC_abort_counter;
extern unsigned int NyLPC_debug_counter;


#if NyLPC_ARCH==NyLPC_ARCH_FREERTOS
	#define NyLPC_OnErrorGoto(l) goto l
#elif NyLPC_ARCH==NyLPC_ARCH_WIN32
	#define NyLPC_OnErrorGoto(l) printf("%s:%d\n",__FILE__,__LINE__); goto l;
#else
#error Bad NyLPC_ARCH!
#endif



/**********************************************************************
 *
 * Basic type
 *
 **********************************************************************/

/**
 * NyLPC_TBoolは、処理系依存の真偽値を返します。
 *
 */
#if NyLPC_ARCH==NyLPC_ARCH_FREERTOS
	typedef portBASE_TYPE NyLPC_TBool;
#elif NyLPC_ARCH==NyLPC_ARCH_WIN32
	typedef int NyLPC_TBool;
#else
#error Bad NyLPC_ARCH!
#endif
#define NyLPC_TBool_TRUE (0==0)
#define NyLPC_TBool_FALSE (0!=0)


typedef char NyLPC_TChar;

typedef char NyLPC_TInt8;
typedef short NyLPC_TInt16;
typedef long NyLPC_TInt32;
//----------------------------------------------------------------------
typedef unsigned char NyLPC_TUInt8;

/**
 * ビット操作関数です。bfのbit bに、1をセットします。
 */
#define NyLPC_TUInt8_setBit(bf,b) NyLPC_TUInt32_setBit(bf,b)
/**
 * ビット操作関数です。bfのbit bに、0をセットします。
 */
#define NyLPC_TUInt8_unsetBit(bf,b) NyLPC_TUInt32_unsetBit(bf,b)
/**
 * ビット操作関数です。bfのbit bが、1であるかテストします。
 */
#define NyLPC_TUInt8_isBitOn(bf,b) NyLPC_TUInt32_isBitOn(bf,b)


#define NyLPC_TUInt8_TRUE NyLPC_TBool_TRUE
#define NyLPC_TUInt8_FALSE NyLPC_TBool_FALSE
#define NyLPC_TUint8_castto_TBool(a) ((a)?NyLPC_TBool_TRUE:NyLPC_TBool_FALSE)

//----------------------------------------------------------------------
typedef unsigned short NyLPC_TUInt16;
/**
 * ビット操作関数です。bfのbit bに、1をセットします。
 */
#define NyLPC_TUInt16_setBit(bf,b) NyLPC_TUInt32_setBit(bf,b)
/**
 * ビット操作関数です。bfのbit bに、0をセットします。
 */
#define NyLPC_TUInt16_unsetBit(bf,b) NyLPC_TUInt32_unsetBit(bf,b)
/**
 * ビット操作関数です。bfのbit bが、1であるかテストします。
 */
#define NyLPC_TUInt16_isBitOn(bf,b) NyLPC_TUInt32_isBitOn(bf,b)


#define NyLPC_TUInt16_BSWAP(n) (((((NyLPC_TUInt16)(n))<< 8)&0xff00)|((((NyLPC_TUInt16)(n))>> 8)&0x00ff))
#define NyLPC_TUInt32_BSWAP(n) (((((NyLPC_TUInt32)(n))<<24)&0xff000000)|((((NyLPC_TUInt32)(n))<< 8)&0x00ff0000)|((((NyLPC_TUInt32)(n))>> 8)&0x0000ff00)|((((NyLPC_TUInt32)(n))>>24)&0x000000ff))


NyLPC_TUInt16 NyLPC_TUInt16_bswap(NyLPC_TUInt16 n);

#define NyLPC_TUInt16_TRUE NyLPC_TBool_TRUE
#define NyLPC_TUInt16_FALSE NyLPC_TBool_FALSE
#define NyLPC_TUint16_castto_TBool(a) ((a)?NyLPC_TBool_TRUE:NyLPC_TBool_FALSE)

//----------------------------------------------------------------------
typedef unsigned long NyLPC_TUInt32;
/**
 * ビット操作関数です。bfのbit bに、1をセットします。
 */
#define NyLPC_TUInt32_setBit(bf,b) bf=(bf|b)
/**
 * ビット操作関数です。bfのbit bに、0をセットします。
 */
#define NyLPC_TUInt32_unsetBit(bf,b) bf=(bf&(~b))
/**
 * ビット操作関数です。bfのbit bが、1であるかテストします。
 */
#define NyLPC_TUInt32_isBitOn(bf,b) ((bf&b)==(b))

NyLPC_TUInt32 NyLPC_TUInt32_bswap(NyLPC_TUInt32 n);

#define NyLPC_TUInt32_TRUE NyLPC_TBool_TRUE
#define NyLPC_TUInt32_FALSE NyLPC_TBool_FALSE

#define NyLPC_TUint16_castto_TBool(a) ((a)?NyLPC_TBool_TRUE:NyLPC_TBool_FALSE)


//----------------------------------------------------------------------

/**
 * ミリ秒を格納する変数型です。
 */
typedef NyLPC_TUInt32 NyLPC_TMSec;
/**
 * ミリ秒です。無限時間を表します。
 */
#define NyLPC_TMSec_INFINITE 0xFFFFFFFF

#if NyLPC_ARCH==NyLPC_ARCH_FREERTOS
	/**
	 * ミリ秒単位をFreeRTOSのTickTimeへ変換します。
	 */
	#define NyLPC_Msec2portTick(ms) ((ms)==NyLPC_TTime_INFINITE?portMAX_DELAY:((ms)/portTICK_RATE_MS))
#elif NyLPC_ARCH==NyLPC_ARCH_WIN32
#else
#error Bad NyLPC_ARCH!
#endif



/*********************************************************************************
 *
 *********************************************************************************/


#include "../NyLPC_cRingBuffer.h"
#include "../NyLPC_cPtrTbl.h"
#include "../NyLPC_cFifoBuffer.h"
#include "../NyLPC_cPtrStream.h"
#include "../NyLPC_cStr.h"


#if NyLPC_ARCH==NyLPC_ARCH_FREERTOS
	#include "../NyLPC_cStopwatch.h"
	#include "../NyLPC_cMutex.h"
	#include "../NyLPC_cThread.h"
#endif



#endif
